import React, { useState, useEffect } from 'react';
import { is_empty, BtSwitch, obj_str, loc_str, FindBarBase, useCmd, WaitUmd, MainView, cline, uJob, adjust, uReal, for_obj, loc } from 'sui';
import { get_init } from 'trace/cmd';
import { utc_offset } from 'cache';
import { ChartS } from './chart/single';
import { set_tp } from './cmd';
import { User } from 'cache';

const SingleView = ({ mod, sideopen }) => {
    const [main_inner, mainInner] = useState();
    const [main_outer, mainOuter] = useState();
    const [pbox, setPbox] = useState(false);
    const [opt_find, optFind] = useState();
    const umd = useCmd(null, "trace");

    useEffect(() => get_init(optFind), []);

    const filter_data = (tp, data, set) => {
        if (is_empty(data)) {
            return null;
        }

        const ret = {};
        ret[`${tp}dia`] = [];
        ret[`${tp}dt`] = [];
        ret[`${tp}width`] = [];

        data.forEach((d, i) => {
            if (set) {
                const sn = obj_str(d, "sn");
                if (!set.has(sn)) {
                    return;
                }
            }

            for_obj(d, (k, v) => {
                if (k.endsWith("dia")) {
                    v = adjust(v);
                }

                if (ret[k]) {
                    ret[k].push(v)
                }
            });
        });

        const tmp = {};

        const setVal = (k) => {
            const key = `${tp}${k}`;
            const v = ret[key];

            tmp[key] = {
                v: v,
                min: Math.min(...v),
                max: Math.max(...v),
            };
        };

        setVal("dt");
        setVal("dia");
        setVal("width");

        return tmp;
    };

    const do_psn = (cmd_inner, cmd_outer, inner_set, outer_set) => {
        const doOut = () => {
            set_tp(cmd_outer);

            uJob(null, "work/batch", cmd_outer,
                r => {
                    const cmd = filter_data("out", r, outer_set);
                    mainOuter(cmd);
                    umd.endWait();
                },
                e => umd.endWait());
        };

        set_tp(cmd_inner);

        uJob(null, "work/batch", cmd_inner,
            r => {
                const cmd = filter_data("in", r, inner_set);
                mainInner(cmd);

                doOut();
            },
            e => doOut());
    };

    const do_pbox = (cmd_inner, cmd_outer) => {
        umd.startWait();

        uReal(null, "pair/pbox",
            {
                line: cline(),
                usn: User.userName(),
            },
            r => {
                const inner_set = new Set();
                const outer_set = new Set();

                if (r.outer) {
                    r.outer.forEach(d => outer_set.add(d));
                }

                if (r.inner) {
                    r.inner.forEach(d => inner_set.add(d));
                }

                do_psn(cmd_inner, cmd_outer, inner_set, outer_set);
            },
            e => umd.setErr(loc("l_803")));
    };

    const hfind = (value) => {
        if (!value["time"]) {
            alert(loc("l_307"));
            return;
        }

        const utc = utc_offset();

        const opt = [
            {ge: "time", v: loc_str(value["t_start"]), utc: utc},
            {le: "time", v: loc_str(value["t_end"]), utc: utc},
            {eq: "line", v: cline()},
        ];

        const psn = obj_str(value, "psn");

        const cmd_inner = {
            line: cline(),
            bsn: psn,
            tp: "in",
            opt: {
                desc: true,
                and: opt,
            }
        };

        const cmd_outer = {
            line: cline(),
            bsn: psn,
            tp: "out",
            opt: {
                desc: true,
                and: opt,
            }
        };

        if (pbox) {
            do_pbox(cmd_inner, cmd_outer);
            return;
        }

        if (!psn) {
            alert(loc("l_307"));
            return;
        }

        umd.startWait();
        do_psn(cmd_inner, cmd_outer);
    };

    const hclear = () => get_init(optFind);

    const ctl = {
        ctl: [
            {sn: "psn", name: loc("l_488")},
            {sn: "time", name: loc("l_308"), ctl: "IkFindDate", start: "t_start", end: "t_end"},
        ]
    };

    const Right = () => (
        <div className="inline-flex mr-3">
            <BtSwitch checked={pbox} hcmd={setPbox} className="ml-2">{loc("l_799")}</BtSwitch>
        </div>
    );

    return (
        <MainView>
            <FindBarBase left={loc("l_798")} hcmd={hfind} data={ctl} hclear={hclear} cur={opt_find} right={<Right/>}/>
            <ChartS cur={main_inner} tp="india" title={`${loc("l_784")} - ${loc("l_746")}`} gc={true} diff={1}/>
            <ChartS cur={main_inner} tp="indt" title={`${loc("l_784")} - ${loc("l_786")}`} gc={true}/>
            <ChartS cur={main_inner} tp="inwidth" title={`${loc("l_784")} - ${loc("l_747")}`} gc={true}/>
            <ChartS cur={main_outer} tp="outdia" title={`${loc("l_783")} - ${loc("l_745")}`} gc={true} diff={1}/>
            <ChartS cur={main_outer} tp="outdt" title={`${loc("l_783")} - ${loc("l_786")}`} gc={true}/>
            <ChartS cur={main_outer} tp="outwidth" title={`${loc("l_783")} - ${loc("l_747")}`} gc={true}/>
            <WaitUmd umd={umd}/>
        </MainView>
    );
};

export {SingleView};
